#include <stdio.h>
#include <stdlib.h>
#include <limits>
#include <iostream>

using namespace std;

#define DUMP_NUMERIC_LIMITS_FUN( type, method )	\
	cout << "    " # method "(): " << numeric_limits < type > ::method() << endl;
#define DUMP_NUMERIC_LIMITS_ATTR( type, attr ) \
	cout << "    " # attr ": " << numeric_limits < type > ::attr << endl;
#define DUMP_LIMIT_VALUES( type ) \
	do { \
		cout << "-------- " # type " :" << endl; \
		cout << "size: " << sizeof( type ) << endl;	\
		DUMP_NUMERIC_LIMITS_FUN( type, min ); \
		DUMP_NUMERIC_LIMITS_FUN( type, max ); \
		DUMP_NUMERIC_LIMITS_FUN( type, epsilon ); \
		DUMP_NUMERIC_LIMITS_FUN( type, round_error ); \
		DUMP_NUMERIC_LIMITS_FUN( type, infinity ); \
		/*DUMP_NUMERIC_LIMITS_FUN( type, quietNaN );*/ \
		/*DUMP_NUMERIC_LIMITS_FUN( type, signalingNaN );*/ \
		DUMP_NUMERIC_LIMITS_FUN( type, denorm_min ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_specialized ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_specialized ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, digits ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, digits10 );	\
		DUMP_NUMERIC_LIMITS_ATTR( type, is_signed ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_integer ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_exact );	\
		DUMP_NUMERIC_LIMITS_ATTR( type, radix ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, min_exponent );	\
		DUMP_NUMERIC_LIMITS_ATTR( type, min_exponent10 ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, max_exponent );	\
		DUMP_NUMERIC_LIMITS_ATTR( type, max_exponent10 ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, has_infinity );	\
		/* DUMP_NUMERIC_LIMITS_ATTR( type, has_quietNaN ); */ \
		/* DUMP_NUMERIC_LIMITS_ATTR( type, has_signalingNaN ); */ \
		DUMP_NUMERIC_LIMITS_ATTR( type, has_denorm ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, has_denorm_loss ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_iec559 ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_bounded ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, is_modulo ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, traps ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, tinyness_before ); \
		DUMP_NUMERIC_LIMITS_ATTR( type, round_style ); \
		cout << endl; \
	} while( 0 )

int main( int argc, char *argv[] )
{
	DUMP_LIMIT_VALUES( short );
	DUMP_LIMIT_VALUES( unsigned short );
	DUMP_LIMIT_VALUES( int );
	DUMP_LIMIT_VALUES( unsigned int );
	DUMP_LIMIT_VALUES( long );
	DUMP_LIMIT_VALUES( unsigned long );
	DUMP_LIMIT_VALUES( long long );
	DUMP_LIMIT_VALUES( unsigned long long );
	DUMP_LIMIT_VALUES( float );
	DUMP_LIMIT_VALUES( double );
	DUMP_LIMIT_VALUES( long double );
	DUMP_LIMIT_VALUES( long double );

	return 0;
}

